package Engine.TileHandling;

import java.awt.Graphics;
import java.util.ArrayList;

import Engine.Utils.Vector2f;

/**
 * Handles the rendering of the tile world.
 * @author Lueko
 *
 */
public class TileRenderer {
    
    private int width, height;
    private int worldWidth, worldHeight;
    private int[] worldTiles;

    public static ArrayList<Tile> tiles = new ArrayList<Tile>();
    
    /**
     * @param width Width of the canvas.
     * @param height Height of the canvas.
     * @param worldWidth Number of tiles in the world in the x axis.
     * @param worldHeight Number of tiles in the world in the y axis.
     * @param tiles Added tiles of the world.
     */
    public TileRenderer(int width, int height, int worldWidth, int worldHeight, int [] tiles) {
        this.width = width;
        this.height = height;
        this.worldWidth = worldWidth;
        this.worldHeight = worldHeight;
        this.worldTiles = tiles;
    }

    /**
     * Renders all tiles in the window.
     * @param g Graphics object to render on.
     * @param mapPos Position of the camera.
     */
    public void renderTiles(Graphics g, Vector2f mapPos) {
        int x0 = (int) (mapPos.getX() - Tile.SIZE) / Tile.SIZE;
        int x1 = ((int) mapPos.getX() + width + Tile.SIZE) / Tile.SIZE;
        int y0 = (int) (mapPos.getY() - Tile.SIZE) / Tile.SIZE;
        int y1 = ((int) mapPos.getY() + height + Tile.SIZE) / Tile.SIZE;

        for (int y = y0; y < y1; y++) {
            for (int x = x0; x < x1; x++) {
                renderTile(mapPos, x * Tile.SIZE, y * Tile.SIZE, getTile(x, y), g);
            }
        }
    }
    
    /**
     * Renders a single tile at a screen position.
     * @param mapPos Position of the camera.
     * @param xp X world position.
     * @param yp Y world position.
     * @param tile The tile to render.
     * @param g Graphics object to render on.
     */
    public void renderTile(Vector2f mapPos, int xp, int yp, Tile tile, Graphics g) {
        xp -= (int) mapPos.getX();
        yp -= (int) mapPos.getY();
        g.drawImage(tile.getTileImage(), xp, yp, Tile.SIZE, Tile.SIZE, null);
    }
    
    /**
     * Returns the tile at the given position.
     * @param x X position as tile raster.
     * @param y Y position as tile raster.
     * @return The tile at the given position.
     */
    public Tile getTile(int x, int y) {
        if (x < 0 || y < 0 || x >= worldWidth || y >= worldHeight) return Tile.err;
        
        for (int i = 0; i < tiles.size(); i++) {
            if (worldTiles[y * worldWidth + x] == tiles.get(i).getColor()) return tiles.get(i);
        }
        
        return Tile.err;
    }

    public int getWidth() {
        return width;
    }

    public void setWidth(int width) {
        this.width = width;
    }

    public int getHeight() {
        return height;
    }

    public void setHeight(int height) {
        this.height = height;
    }

    public int getWorldWidth() {
        return worldWidth;
    }

    public void setWorldWidth(int worldWidth) {
        this.worldWidth = worldWidth;
    }

    public int getWorldHeight() {
        return worldHeight;
    }

    public void setWorldHeight(int worldHeight) {
        this.worldHeight = worldHeight;
    }

    public int[] getTiles() {
        return worldTiles;
    }

    public void setTiles(int[] tiles) {
        this.worldTiles = tiles;
    }
    
}
